home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
kernel
/
ofs
/
ofsDisk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-18
|
27KB
|
844 lines
/*
* ofsDisk.c --
*
* Routines related to managing local disks under the orginial sprite
* file system.
*
* Copyright 1987 Regents of the University of California
* All rights reserved.
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies. The University of California
* makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#ifndef lint
static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/ofs/ofsDisk.c,v 9.15 92/03/19 17:34:40 jhh Exp $ SPRITE (Berkeley)";
#endif not lint
#include <sprite.h>
#include <fs.h>
#include <fsutil.h>
#include <fsdm.h>
#include <fslcl.h>
#include <fsNameOps.h>
#include <fsio.h>
#include <fsprefix.h>
#include <fsconsist.h>
#include <devDiskLabel.h>
#include <dev.h>
#include <devFsOpTable.h>
#include <sync.h>
#include <rpc.h>
#include <fsioDevice.h>
#include <ofs.h>
#include <stdio.h>
static Fsdm_DomainOps ofsDomainOps = {
Ofs_AttachDisk,
Ofs_DetachDisk,
Ofs_DomainWriteBack,
Ofs_RereadSummaryInfo,
Ofs_DomainInfo,
Ofs_BlockAllocate,
Ofs_GetNewFileNumber,
Ofs_FreeFileNumber,
Ofs_FileDescInit,
Ofs_FileDescFetch,
Ofs_FileDescStore,
Ofs_FileBlockRead,
Ofs_FileBlockWrite,
Ofs_FileTrunc,
Ofs_DirOpStart,
Ofs_DirOpEnd
};
static Fscache_BackendRoutines ofsBackendRoutines = {
Fsdm_BlockAllocate,
Fsdm_FileTrunc,
Fsdm_FileBlockRead,
Fsdm_FileBlockWrite,
Ofs_ReallocBlock,
Ofs_StartWriteBack,
};
static Fscache_Backend *cacheBackendPtr = (Fscache_Backend *) NIL;
/*
*----------------------------------------------------------------------
*
* Ofs_Init --
*
* Initialized code of the OFS disk storage manager module.
*
* Results:
*
* Side effects:
* Registers OFS with Fsdm module.
*
*----------------------------------------------------------------------
*/
void
Ofs_Init()
{
Fsdm_RegisterDiskManager("OFS", Ofs_AttachDisk);
}
/*
*----------------------------------------------------------------------
*
* Ofs_AttachDisk --
*
* Try to attach a OFS disk from the specified disk.
*
* Results:
*
* Side effects:
*
*----------------------------------------------------------------------
*/
ReturnStatus
Ofs_AttachDisk(devicePtr, localName, flags, domainNumPtr)
Fs_Device *devicePtr; /* Device containing file system. */
char *localName; /* The local prefix for the domain */
int flags; /* Attach flags. */
int *domainNumPtr; /* OUT: Domain number allocated. */
{
ReturnStatus status; /* Error code */
register Address buffer; /* Read buffer */
int headerSector; /* Starting sector of domain header */
int numHeaderSectors; /* Number of sectors in domain header */
int summarySector; /* Sector of summary information. */
Ofs_SummaryInfo *summaryInfoPtr; /* Pointer to summary info. */
Fs_IOParam io; /* I/O Parameter block */
Fs_IOReply reply; /* Results of I/O */
int partition;
Fsdm_Domain *domainPtr;
Ofs_Domain *ofsPtr;
headerSector = summarySector = 0;
bzero((Address)&io, sizeof(io));
bzero((Address)&reply, sizeof(reply));
/*
* Read the zero'th sector of the partition. It has a copy of the
* zero'th sector of the whole disk which describes how the rest of the
* domain's zero'th cylinder is layed out.
*/
buffer = (Address)malloc(DEV_BYTES_PER_SECTOR * OFS_NUM_DOMAIN_SECTORS);
io.buffer = buffer;
io.length = DEV_BYTES_PER_SECTOR;
io.offset = 0;
status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)(devicePtr,
&io, &reply);
if (status != SUCCESS) {
free(buffer);
return(status);
}
/*
* Check for different disk formats, and figure out how the rest
* of the zero'th cylinder is layed out.
*/
if (Fsdm_IsSunLabel(buffer)) {
Ofs_DomainHeader *domainHeaderPtr = (Ofs_DomainHeader *) buffer;
int i;
/*
* For Sun formatted disks we put the domain header well past
* the disk label and the boot program.
*/
numHeaderSectors = OFS_NUM_DOMAIN_SECTORS;
io.length = DEV_BYTES_PER_SECTOR * OFS_NUM_DOMAIN_SECTORS;
for (i = 2; i < FSDM_MAX_BOOT_SECTORS + 3; i+= FSDM_BOOT_SECTOR_INC) {
io.offset = i * DEV_BYTES_PER_SECTOR;
io.length = DEV_BYTES_PER_SECTOR * OFS_NUM_DOMAIN_SECTORS;
status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
(devicePtr, &io, &reply);
if (status != SUCCESS) {
free(buffer);
return(status);
}
if (domainHeaderPtr->magic == OFS_DOMAIN_MAGIC) {
headerSector = i;
summarySector = i - 1;
break;
}
}
if (i >= FSDM_MAX_BOOT_SECTORS + 3) {
free(buffer);
return(FAILURE);
}
} else if (Fsdm_IsSpriteLabel(buffer)) {
register Fsdm_DiskHeader *diskHeaderPtr;
diskHeaderPtr = (Fsdm_DiskHeader *)buffer;
headerSector = diskHeaderPtr->domainSector;
numHeaderSectors = diskHeaderPtr->numDomainSectors;
summarySector = diskHeaderPtr->summarySector;
} else {
io.buffer = buffer;
io.length = DEV_BYTES_PER_SECTOR;
io.offset = DEC_LABEL_SECTOR * DEV_BYTES_PER_SECTOR;
status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
(devicePtr, &io, &reply);
if (status != SUCCESS) {
free(buffer);
return(status);
}
if (Fsdm_IsDecLabel(buffer)){
register Dec_DiskLabel *decLabelPtr;
decLabelPtr = (Dec_DiskLabel *)buffer;
headerSector = decLabelPtr->domainSector;
numHeaderSectors = decLabelPtr->numDomainSectors;
summarySector = decLabelPtr->summarySector;
if (summarySector < 0) {
free(buffer);
return(FAILURE);
}
} else {
free(buffer);
return(FAILURE);
}
}
/*
* Read in summary information.
*/
io.length = DEV_BYTES_PER_SECTOR;
io.offset = summarySector * DEV_BYTES_PER_SECTOR;
status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
(devicePtr, &io, &reply);
if (status != SUCCESS) {
free(buffer);
return(status);
}
summaryInfoPtr = (Ofs_SummaryInfo *) buffer;
/*
* Read the domain header and save it with the domain state.
*/
buffer = (Address)malloc(DEV_BYTES_PER_SECTOR * numHeaderSectors);
io.buffer = buffer;
io.length = numHeaderSectors * DEV_BYTES_PER_SECTOR;
io.offset = headerSector * DEV_BYTES_PER_SECTOR;
status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)(devicePtr,
&io, &reply);
if (status != SUCCESS) {
free((char *) summaryInfoPtr);
free(buffer);
return(status);
} else if (((Ofs_DomainHeader *)buffer)->magic != OFS_DOMAIN_MAGIC) {
free((char *) summaryInfoPtr);
free(buffer);
return(FAILURE);
}
/*
* Make the domain flag positive to inform caller that this is an
* OFS file system even if the mount fails.
*/
*domainNumPtr = 1;
/*
* Verify the device specification by checking the partition
* number kept in the domain header.
*/
partition = ((Ofs_DomainHeader *)buffer)->device.unit;
if (partition >= 0 && partition < FSDM_NUM_DISK_PARTS) {
if ((devicePtr->unit % FSDM_NUM_DISK_PARTS) != partition) {
/*
* File system was built on a different partition.
*/
free((char *) summaryInfoPtr);
free(buffer);
return(FAILURE);
}
}
status = Fsdm_InstallDomain(summaryInfoPtr->domainNumber,
((Ofs_DomainHeader *)buffer)->device.serverID,
localName, flags, &domainPtr);
if (status != SUCCESS) {
if (status == FS_FILE_BUSY) {
if (domainPtr->flags & FSDM_DOMAIN_ATTACH_BOOT) {
domainPtr->flags &= ~FSDM_DOMAIN_ATTACH_BOOT;
summaryInfoPtr->flags &= ~OFS_DOMAIN_JUST_CHECKED;
printf("Ofs_AttachDisk: clearing just-checked bit\n");
if ((flags & FS_ATTACH_READ_ONLY) == 0) {
io.buffer = (char *) summaryInfoPtr;
io.length = DEV_BYTES_PER_SECTOR;
io.offset = summarySector * DEV_BYTES_PER_SECTOR;
status =
(*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].write)
(devicePtr, &io, &reply);
if (status != SUCCESS) {
panic(
"Ofs_AttachDisk: Summary write failed, status %x\n", status);
}
}
}
status = FS_DOMAIN_UNAVAILABLE;
}
free((char *) summaryInfoPtr);
free(buffer);
return status;
}
if (cacheBackendPtr == (Fscache_Backend *) NIL) {
cacheBackendPtr =
Fscache_RegisterBackend(&ofsBackendRoutines,(ClientData) 0, 0);
}
ofsPtr = (Ofs_Domain *) malloc(sizeof(Ofs_Domain));
bzero((char *) ofsPtr, sizeof(Ofs_Domain));
domainPtr->backendPtr = cacheBackendPtr;
domainPtr->domainOpsPtr = &ofsDomainOps;
domainPtr->clientData = (ClientData) ofsPtr;
ofsPtr->domainPtr = domainPtr;
ofsPtr->headerPtr = (Ofs_DomainHeader *) buffer;
ofsPtr->summaryInfoPtr = summaryInfoPtr;
ofsPtr->summarySector = summarySector;
ofsPtr->blockDevHandlePtr = (DevBlockDeviceHandle *) (devicePtr->data);
/*
* Fix up the device information in the domain header
* as this is used by the block I/O routines.
*/
ofsPtr->headerPtr->device.unit = devicePtr->unit;
ofsPtr->headerPtr->device.type = devicePtr->type;
ofsPtr->headerPtr->device.data = devicePtr->data;
/*
* After reading the low level header information from the disk we
* install the domain into the set of active domains and initialize
* things for block I/O.
*/
status = OfsIOInit(domainPtr);
if (status != SUCCESS) {
printf( "Ofs_InitializeDomain: can't initialize block I/O %x\n",
status);
domainPtr->flags |= FSDM_DOMAIN_DOWN;
return(status);
}
/*
* Set the domainNumber in the summary info so next time we will be
* mounted under the same domain number.
*/
summaryInfoPtr->domainNumber = domainPtr->domainNumber;
*domainNumPtr = domainPtr->domainNumber;
/*
* Finally mark the domain to indicate that if we go down hard,
* clean recovery of this domain is impossible.
*/
if ((summaryInfoPtr->flags & OFS_DOMAIN_NOT_SAFE) == 0) {
summaryInfoPtr->flags |= OFS_DOMAIN_ATTACHED_CLEAN;
} else {
summaryInfoPtr->flags &= ~OFS_DOMAIN_ATTACHED_CLEAN;
}
summaryInfoPtr->flags |= OFS_DOMAIN_NOT_SAFE |
OFS_DOMAIN_TIMES_VALID;
if (!(flags & FS_DEFAULT_DOMAIN)) {
summaryInfoPtr->flags &= ~OFS_DOMAIN_JUST_CHECKED;
}
summaryInfoPtr->attachSeconds = Fsutil_TimeInSeconds();
if ((flags & FS_ATTACH_READ_ONLY) == 0) {
status = OfsWriteBackSummaryInfo(ofsPtr);
if (status != SUCCESS) {
panic( "Ofs_AttachDisk: Summary write failed, status %x\n", status);
}
}
return status;
}
/*
*----------------------------------------------------------------------
*
* OfsIOInit --
*
* Initialize a particular local domain for I/O.
*
* Results:
* Error code returned from initializing data block and file
* descriptor allocation.
*
* Side effects:
* Physical file handle for the domain is initialized.
*
*----------------------------------------------------------------------
*/
ReturnStatus
OfsIOInit(domainPtr)
Fsdm_Domain *domainPtr;
{
register Ofs_Domain *ofsPtr;
ReturnStatus status;
Fscache_Attributes attr;
int domainNumber;
ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
domainNumber = domainPtr->domainNumber;
/*
* Initialize the file handle used for raw I/O, i.e. for file descriptors,
* the bitmaps, and indirect blocks.
*/
bzero((Address)&ofsPtr->physHandle, sizeof(ofsPtr->physHandle));
ofsPtr->physHandle.hdr.fileID.major = domainNumber;
ofsPtr->physHandle.hdr.fileID.minor = 0;
ofsPtr->physHandle.hdr.fileID.type = FSIO_LCL_FILE_STREAM;
ofsPtr->physHandle.descPtr = (Fsdm_FileDescriptor *)NIL;
bzero((Address)&attr, sizeof(attr));
attr.lastByte = 0x7fffffff;
Fscache_FileInfoInit(&ofsPtr->physHandle.cacheInfo,
(Fs_HandleHeader *) &ofsPtr->physHandle,
0, TRUE, &attr, domainPtr->backendPtr);
status = OfsBlockAllocInit(ofsPtr);
if (status != SUCCESS) {
printf( "Block Alloc init failed for domain %d\n",
domainNumber);
return(status);
}
status = OfsFileDescAllocInit(ofsPtr);
if (status != SUCCESS) {
printf( "File Desc alloc init failed for domain %d\n",
domainNumber);
return(status);
}
return(status);
}
/*
*----------------------------------------------------------------------
*
* Ofs_DetachDisk --
*
* Remove a local domain from the set of accessible domains.
*
* Results:
* SUCCESS if the domain was already attached and all the outstanding
* file handles could be recalled.
*
* Side effects:
* Clears the prefix table entry for the domain.
*
*----------------------------------------------------------------------
*/
ReturnStatus
Ofs_DetachDisk(domainPtr)
Fsdm_Domain *domainPtr;
{
register Ofs_Domain *ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
Ofs_DomainHeader *headerPtr;
int i;
ReturnStatus status;
int blocksLeft, blocksSkipped;
/*
* Write all dirty blocks, bitmaps, etc. to disk and take the
* domain down.
*/
Fscache_WriteBack(-1, &blocksLeft, FALSE); /* Write back the cache. */
headerPtr = ofsPtr->headerPtr;
Fscache_FileWriteBack(&ofsPtr->physHandle.cacheInfo,
headerPtr->fileDescOffset,
headerPtr->fileDescOffset +
(headerPtr->numFileDesc / FSDM_FILE_DESC_PER_BLOCK) + 1,
FSCACHE_WRITE_BACK_AND_INVALIDATE, &blocksSkipped);
Fsdm_DomainWriteBack(ofsPtr->physHandle.hdr.fileID.major, FALSE, TRUE);
/* Write back domain info. */
/*
* We successfully brought down the disk, so mark it as OK.
* The detach time is noted in order to track how long disks are available.
*/
ofsPtr->summaryInfoPtr->flags &= ~OFS_DOMAIN_NOT_SAFE;
ofsPtr->summaryInfoPtr->flags &= ~OFS_DOMAIN_JUST_CHECKED;
ofsPtr->summaryInfoPtr->detachSeconds = Fsutil_TimeInSeconds();
status = OfsWriteBackSummaryInfo(ofsPtr);
if (status != SUCCESS) {
panic( "Ofs_DetachDisk: Summary write failed, status %x\n",
status);
}
/*
* Free up resources for the domain.
*/
Sync_LockClear(&ofsPtr->dataBlockLock);
Sync_LockClear(&ofsPtr->fileDescLock);
free((Address)ofsPtr->headerPtr);
free((Address)ofsPtr->summaryInfoPtr);
free((Address)ofsPtr->dataBlockBitmap);
free((Address)ofsPtr->cylinders);
for (i = 0; i < OFS_NUM_FRAG_SIZES; i++) {
List_Links *fragList;
OfsFragment *fragPtr;
fragList = ofsPtr->fragLists[i];
while (!List_IsEmpty(fragList)) {
fragPtr = (OfsFragment *)List_First(fragList);
List_Remove((List_Links *)fragPtr);
free((Address)fragPtr);
}
free((Address)fragList);
}
free((Address)ofsPtr->fileDescBitmap);
return(SUCCESS);
}
/*
*----------------------------------------------------------------------
*
* Ofs_DomainWriteBack --
*
* Force all domain information to disk.
*
* Results:
* Error code if the write failed.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
ReturnStatus
Ofs_DomainWriteBack(domainPtr, shutdown)
Fsdm_Domain *domainPtr; /* Domain to writeback. */
Boolean shutdown; /* TRUE if are syncing to shutdown the system.*/
{
register Ofs_Domain *ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
ReturnStatus status1, status2;
status1 = OfsWriteBackDataBlockBitmap(ofsPtr);
status2 = OfsWriteBackFileDescBitmap(ofsPtr);
if (shutdown && status1 == SUCCESS && status2 == SUCCESS) {
ofsPtr->summaryInfoPtr->flags &= ~OFS_DOMAIN_NOT_SAFE;
ofsPtr->summaryInfoPtr->detachSeconds = Fsutil_TimeInSeconds();
} else {
ofsPtr->summaryInfoPtr->flags |= OFS_DOMAIN_NOT_SAFE;
}
(void)OfsWriteBackSummaryInfo(ofsPtr);
return (status1 == SUCCESS) ? status2 : status1;
}
/*
*----------------------------------------------------------------------
* The following routines are used by device drivers to map from block
* and sector numbers to disk addresses. There are two sets, one for
* drivers that use logical sector numbers (i.e. SCSI) and the other
* for <cyl,head,sector> format disk addresses.
*----------------------------------------------------------------------
*/
/*
*----------------------------------------------------------------------
*
* OfsBlocksToSectors --
*
* Convert from block indexes (actually, fragment indexes) to
* sectors using the geometry information on the disk. This
* is a utility for block device drivers.
*
* Results:
* The sector number that corresponds to the fragment index.
* The caller has to make sure that its I/O doesn't cross a
* filesystem block boundary.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
#define SECTORS_PER_FRAG (FS_FRAGMENT_SIZE / DEV_BYTES_PER_SECTOR)
int
OfsBlocksToSectors(fragNumber, geoPtr)
int fragNumber; /* Fragment index to map into block index */
register Ofs_Geometry *geoPtr; /* ClientData from the device info */
{
register int sectorNumber; /* The sector corresponding to the fragment */
register int cylinder; /* The cylinder number of the fragment */
register int rotationalSet; /* The rotational set with cylinder of frag */
register int blockNumber; /* The block number within rotational set */
blockNumber = fragNumber / FS_FRAGMENTS_PER_BLOCK;
cylinder = blockNumber / geoPtr->blocksPerCylinder;
/*
* This is the old way of doing things. We have to deal with rotational
* sets and the like.
*/
if (geoPtr->rotSetsPerCyl > 0) {
blockNumber -= cylinder * geoPtr->blocksPerCylinder;
rotationalSet = blockNumber / geoPtr->blocksPerRotSet;
blockNumber -= rotationalSet * geoPtr->blocksPerRotSet;
sectorNumber = geoPtr->sectorsPerTrack * geoPtr->numHeads * cylinder +
geoPtr->sectorsPerTrack * geoPtr->tracksPerRotSet *
rotationalSet +
geoPtr->blockOffset[blockNumber];
sectorNumber += (fragNumber % FS_FRAGMENTS_PER_BLOCK) *
SECTORS_PER_FRAG;
} else if (geoPtr->rotSetsPerCyl == OFS_SCSI_MAPPING) {
/*
* The new way is to map blocks from the start of the disk without
* regard for rotational sets. There is essentially one rotational
* set per disk.
*/
sectorNumber = geoPtr->sectorsPerTrack * geoPtr->numHeads * cylinder +
fragNumber * SECTORS_PER_FRAG - cylinder *
geoPtr->blocksPerCylinder * FS_FRAGMENTS_PER_BLOCK *
SECTORS_PER_FRAG;
} else {
panic("Unknown mapping in domain geometry information\n");
sectorNumber = -1;
}
return(sectorNumber);
}
/*
*----------------------------------------------------------------------
*
* Ofs_BlocksToDiskAddr --
*
* Convert from block indexes (actually, fragment indexes) to
* disk address (head, cylinder, sector) using the geometry information
* on the disk. This is a utility for block device drivers.
*
* Results:
* The disk address that corresponds to the disk address.
* The caller has to make sure that its I/O doesn't cross a
* filesystem block boundary.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Ofs_BlocksToDiskAddr(fragNumber, data, diskAddrPtr)
int fragNumber; /* Fragment index to map into block index */
ClientData data; /* ClientData from the device info */
Dev_DiskAddr *diskAddrPtr;
{
register Ofs_Geometry *geoPtr;
register int sectorNumber; /* The sector corresponding to the fragment */
register int cylinder; /* The cylinder number of the fragment */
register int rotationalSet; /* The rotational set with cylinder of frag */
register int blockNumber; /* The block number within rotational set */
geoPtr = (Ofs_Geometry *)data;
/*
* Map to block number because the rotational sets are laid out
* relative to blocks. After that the cylinder is easy because we know
* blocksPerCylinder. To get the head and sector we first get the
* rotational set (described in fsDisk.h) of the block and the
* block's sector offset (relative to the rotational set!). This complex
* algorithm crops up because there isn't necessarily an even number
* of blocks per track. The 'blockOffset' array in the geometry gives
* a sector index of each successive block in a rotational set. Finally,
* we can use the sectorsPerTrack to get the head and sector.
*/
blockNumber = fragNumber / FS_FRAGMENTS_PER_BLOCK;
cylinder = blockNumber / geoPtr->blocksPerCylinder;
blockNumber -= cylinder * geoPtr->blocksPerCylinder;
diskAddrPtr->cylinder = cylinder;
rotationalSet = blockNumber / geoPtr->blocksPerRotSet;
blockNumber -= rotationalSet * geoPtr->blocksPerRotSet;
/*
* The follow statment had to be broken into two because the compiler used
* register d2 to do the modulo operation, but wasn't saving its value.
*/
sectorNumber = geoPtr->sectorsPerTrack * geoPtr->tracksPerRotSet *
rotationalSet + geoPtr->blockOffset[blockNumber];
sectorNumber +=
(fragNumber % FS_FRAGMENTS_PER_BLOCK) * SECTORS_PER_FRAG;
diskAddrPtr->head = sectorNumber / geoPtr->sectorsPerTrack;
diskAddrPtr->sector = sectorNumber -
diskAddrPtr->head * geoPtr->sectorsPerTrack;
}
/*
*----------------------------------------------------------------------
*
* Ofs_SectorsToRawDiskAddr --
*
* Convert from a sector offset to a raw disk address (cyl, head,
* sector) using the geometry information on the disk. This is a
* utility for raw device drivers and does not pay attention to the
* rotational position of filesystem disk blocks.
*
* This should be moved to Dev
*
* Results:
* The disk address that corresponds exactly to the byte offset.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ofs_SectorsToRawDiskAddr(sector, numSectors, numHeads, diskAddrPtr)
int sector; /* Sector number (counting from zero 'til the total
* number of sectors in the disk) */
int numSectors; /* Number of sectors per track */
int numHeads; /* Number of heads on the disk */
Dev_DiskAddr *diskAddrPtr;
{
register int sectorsPerCyl; /* The rotational set with cylinder of frag */
sectorsPerCyl = numSectors * numHeads;
diskAddrPtr->cylinder = sector / sectorsPerCyl;
sector -= diskAddrPtr->cylinder * sectorsPerCyl;
diskAddrPtr->head = sector / numSectors;
diskAddrPtr->sector = sector - numSectors * diskAddrPtr->head;
return 0;
}
/*
*----------------------------------------------------------------------
*
* Ofs_RereadSummaryInfo --
*
* Reread the summary sector associated with the prefix and update
* the domain information. This should be called if the summary
* sector on the disk has been changed since the domain was attached.
*
* Results:
* SUCCESS if the summary sector was read correctly and the
* information was updated
*
* Side effects:
* The summary sector information associated with the domain is
* updated.
*
*----------------------------------------------------------------------
*/
ReturnStatus
Ofs_RereadSummaryInfo(domainPtr)
Fsdm_Domain *domainPtr; /* Domain to reread summary for. */
{
register Ofs_Domain *ofsPtr = OFS_PTR_FROM_DOMAIN(domainPtr);
ReturnStatus status;
Fs_Device *devicePtr;
Fs_IOParam io;
Fs_IOReply reply;
char buffer[DEV_BYTES_PER_SECTOR];
bzero((Address)&io, sizeof(io));
bzero((Address)&reply, sizeof(reply));
devicePtr = &(ofsPtr->headerPtr->device);
io.buffer = buffer;
io.length = DEV_BYTES_PER_SECTOR;
io.offset = ofsPtr->summarySector * DEV_BYTES_PER_SECTOR;
status = (*devFsOpTable[DEV_TYPE_INDEX(devicePtr->type)].read)
(devicePtr, &io, &reply);
/*
* Copy information from the buffer.
*/
if (status == SUCCESS) {
bcopy(buffer, (char *)ofsPtr->summaryInfoPtr, reply.length);
}
return status;
}
/*
*----------------------------------------------------------------------
*
* Ofs_DirOpStart --
*
* Mark the start of a directory operation on an OFS file system.
* Since OFS uses fscheck to do crash recovery, this is a noop.
*
* Results:
* NIL
*
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
ClientData
Ofs_DirOpStart(domainPtr, opFlags, name, nameLen, fileNumber, fileDescPtr,
dirFileNumber, dirOffset, dirFileDescPtr)
Fsdm_Domain *domainPtr; /* Domain containing the object being modified.
*/
int opFlags; /* Operation code and flags. See fsdm.h for
* definitions. */
char *name; /* Name of object being operated on. */
int nameLen; /* Length in characters of name. */
int fileNumber; /* File number of objecting being operated on.*/
Fsdm_FileDescriptor *fileDescPtr; /* FileDescriptor object being operated on
* before operation starts. */
int dirFileNumber; /* File number of directory containing object.*/
int dirOffset; /* Byte offset into directory of the directory
* entry containing operation. */
Fsdm_FileDescriptor *dirFileDescPtr; /* FileDescriptor of directory before
* operation starts. */
{
return (ClientData) -1;
}
/*
*----------------------------------------------------------------------
*
* Ofs_DirOpEnd --
*
* Mark the end of a directory operation on an OFS file system.
* Since OFS uses fscheck to do crash recovery, this is a noop.
*
* Results:
* None
*
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Ofs_DirOpEnd(domainPtr, clientData, status, opFlags, name, nameLen,
fileNumber, fileDescPtr, dirFileNumber, dirOffset,
dirFileDescPtr)
Fsdm_Domain *domainPtr; /* Domain containing the object modified. */
ClientData clientData; /* ClientData as returned by DirOpStart. */
ReturnStatus status; /* Return status of the operation, SUCCESS if
* operation succeeded. FAILURE otherwise. */
int opFlags; /* Operation code and flags. See fsdm.h for
* definitions. */
char *name; /* Name of object being operated on. */
int nameLen; /* Length in characters of name. */
int fileNumber; /* File number of objecting being operated on.*/
Fsdm_FileDescriptor *fileDescPtr; /* FileDescriptor object after
* operation.*/
int dirFileNumber; /* File number of directory containing object.*/
int dirOffset; /* Byte offset into directory of the directory
* entry containing operation. */
Fsdm_FileDescriptor *dirFileDescPtr; /* FileDescriptor of directory after
* operation. */
{
return;
}